package com.jinzhi.jzweb.controller;


import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.jinzhi.common.annotation.Log;
import com.jinzhi.common.base.BaseController;
import com.jinzhi.common.domain.DictDO;
import com.jinzhi.common.service.DictService;
import com.jinzhi.common.type.EnumErrorCode;
import com.jinzhi.common.utils.EhCacheUtil;
import com.jinzhi.common.utils.Result;
import com.jinzhi.common.utils.StringUtil;
import com.jinzhi.jzweb.domain.*;
import com.jinzhi.jzweb.domain.vo.RecruitmentNowVo;
import com.jinzhi.jzweb.pojo.ErroeDownVo;
import com.jinzhi.jzweb.pojo.ErrorCodeVo;
import com.jinzhi.jzweb.pojo.TrainingCerVo;
import com.jinzhi.jzweb.service.OrganizationNewsService;
import com.jinzhi.jzweb.service.OrganizationRolesService;
import com.jinzhi.jzweb.service.RecruitmentNewsService;
import com.jinzhi.jzweb.utils.EasyPoiUtil;
import com.jinzhi.jzweb.utils.FileUtil;
import com.jinzhi.jzweb.utils.ValuesUtil;
import com.jinzhi.oss.service.OssService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <pre>
 * 招聘信息
 * </pre>
 * <small> 2020-02-24 21:00:11 | lance</small>
 */
@Controller
@Slf4j
@RequestMapping("/jzweb/recruitmentNews")
public class RecruitmentNewsController extends BaseController {
    @Autowired
    private RecruitmentNewsService recruitmentNewsService;
    @Autowired
    private OrganizationNewsService organizationNewsService;
    @Autowired
    private OrganizationRolesService organizationRolesService;
    @Autowired
    private DictService sysDictService;
    @Autowired
    private OssService ossService;
    @GetMapping()
    @RequiresPermissions("jzweb:recruitmentNews:recruitmentNews")
    String RecruitmentNews() {
        return "jzweb/recruitmentNews/recruitmentNews";
    }

    @ResponseBody
    @GetMapping("/list")
    @RequiresPermissions("jzweb:recruitmentNews:recruitmentNews")
    public Result<Page<RecruitmentNewsDO>> list(RecruitmentNewsDO recruitmentNewsDTO) {

        Wrapper<RecruitmentNewsDO> wrapper = new EntityWrapper<RecruitmentNewsDO>().orderBy("id", false);
        if (recruitmentNewsDTO.getState() != null) {
            wrapper.eq("state", recruitmentNewsDTO.getState());
        }
        if (recruitmentNewsDTO.getIsTop() != null) {
            wrapper.eq("is_top", recruitmentNewsDTO.getIsTop());
        }
        if( StringUtil.notEmpty(recruitmentNewsDTO.getName())){
            wrapper.like("name", recruitmentNewsDTO.getName());
        }

        if (StringUtils.isNotBlank(recruitmentNewsDTO.getOrgName())){
            wrapper.like("org_name",recruitmentNewsDTO.getOrgName());
        }
        String roleName = getRoleNames();//查询用户角色
//        if (!roleName.contains("超级用户角色")&&!roleName.contains("简历发布")) {
//            wrapper.eq("org_name",this.getUser().getOrgName());
//        }else {
//            if (StringUtils.isNotBlank(recruitmentNewsDTO.getOrgName())){
//                wrapper.like("org_name",recruitmentNewsDTO.getOrgName());
//            }
//        }

        Page<RecruitmentNewsDO> page = recruitmentNewsService.selectPage(getPage(RecruitmentNewsDO.class), wrapper);
        List list = new ArrayList();
        for (int i = 0; i < page.getRecords().size(); i++) {
            RecruitmentNewsDO obj = (RecruitmentNewsDO) page.getRecords().get(i);
            list.add(obj);
        }
        page.setRecords(list);
        return Result.ok(page);
    }

    /**
     * 批量审核
     * @return
     */
    @PostMapping ("/review")
    @ResponseBody
    @RequiresPermissions("jzweb:recruitmentNews:review")
   public Result<String>  review(@RequestParam("ids[]") Long[] ids,String remark,Integer state) {
        String rerutnS="";

        int i = 0;
        int j = 0;
        for (Long id : ids) {
            RecruitmentNewsDO recruitmentNewsDO = recruitmentNewsService.selectById(id);
            if(recruitmentNewsDO==null){
                return Result.build(0,"该信息未绑定企业，不能进行审核！" );

            }
                Wrapper<OrganizationRolesDO> wrapper = new EntityWrapper<OrganizationRolesDO>();

//                wrapper.eq("org_id", recruitmentNewsDO.getOrgId());
            wrapper.like("org_name", recruitmentNewsDO.getOrgName());
                wrapper.eq("checker_state", 1);

          List list=  organizationRolesService.selectList(wrapper);
            if(list.size()>0){
                if(recruitmentNewsDO != null){
                    recruitmentNewsDO.setStatus(state);
                    recruitmentNewsDO.setCheckerId(this.getUserId());
                    recruitmentNewsDO.setCheckerDate(new Date());
                    if(state.equals(2)){
                        recruitmentNewsDO.setRemarks(remark);//未通过，添加备注
                    }else{
                        recruitmentNewsDO.setRemarks("");//审核通过，清空备注
                    }
                    boolean b = recruitmentNewsService.updateById(recruitmentNewsDO);
                    if (b) {
                        i++;
                    } else {
                        break;
                    }
                }
            }else {
                j++;
            }

        }

        if (i == ids.length) {
            return Result.build(0,"已成功审核：" + i + "条数据");
        } else {
            if(j>0){
                return Result.build(0,"已成功审核：" + i + "条数据"+"失败："+j+"失败原因，企业信息未进行审核！");
            }else {
                return Result.build(0,"已成功审核：" + i + "条数据");
            }

        }
    }

    @Log("机构搜索下拉框")
    @ResponseBody
    @GetMapping("/selOrgList")
    public Result<List<OrganizationNewsDO>> selOrgList(Model model) {
        Wrapper<OrganizationNewsDO> wrapper = new EntityWrapper<OrganizationNewsDO>().orderBy("id", false);
        List<OrganizationNewsDO> organizationNewsDOList = organizationNewsService.selectList(wrapper);
        model.addAttribute("organizationNewsDOList",organizationNewsDOList);
        return Result.ok(organizationNewsDOList);
    }

    @GetMapping("/add")
    @RequiresPermissions("jzweb:recruitmentNews:add")
    String add(Model model) {
        //查询用户角色
        String roleName = getRoleNames();
        if (!roleName.contains("超级用户角色")) {
            OrganizationNewsDO organizationNewsDO = organizationNewsService.selectById(this.getUser().getOrgId());
            model.addAttribute("orgRole", organizationNewsDO);
        }else{
            model.addAttribute("orgRole", organizationRolesService.selByRoleType(3));
        }


        Map map1money = new HashMap();
        map1money.put("Type","moneyList");
        List<DictDO>  listMoney=sysDictService.selectListBy(map1money);
        model.addAttribute("listMoney",listMoney);

        Map map1 = new HashMap();
        map1.put("Type","experience");

        List<DictDO>  experienceList=sysDictService.selectListBy(map1);
        model.addAttribute("experienceList",experienceList);
        return "jzweb/recruitmentNews/add";
    }

    @GetMapping("/edit/{id}")
    @RequiresPermissions("jzweb:recruitmentNews:edit")
    String edit(@PathVariable("id") Long id, Model model) {
        //查询用户角色
        String roleName = getRoleNames();
        if (!roleName.contains("超级用户角色")) {
            OrganizationNewsDO organizationNewsDO = organizationNewsService.selectById(this.getUser().getOrgId());
            model.addAttribute("orgRole", organizationNewsDO);
        }else{
            model.addAttribute("orgRole", organizationRolesService.selByRoleType(3));
        }
        RecruitmentNewsDO recruitmentNews = recruitmentNewsService.selectById(id);
//        OrganizationNewsDO organizationNewsDO = organizationNewsService.selectById(recruitmentNews.getOrgId());
//        recruitmentNews.setOrgName(organizationNewsDO.getName());
        model.addAttribute("recruitmentNews", recruitmentNews);
        Map map1money = new HashMap();
        map1money.put("Type","moneyList");
        List<DictDO>  listMoney=sysDictService.selectListBy(map1money);
        model.addAttribute("listMoney",listMoney);

        Map map1 = new HashMap();
        map1.put("Type","experience");

        List<DictDO>  experienceList=sysDictService.selectListBy(map1);
        model.addAttribute("experienceList",experienceList);
        return "jzweb/recruitmentNews/edit";
    }

    @GetMapping("/info/{id}")
    @RequiresPermissions("jzweb:recruitmentNews:recruitmentNews")
    String info(@PathVariable("id") Long id, Model model) {
        RecruitmentNewsDO recruitmentNews = recruitmentNewsService.selectById(id);
//        if (recruitmentNews.getOrgId() != null) {
//            OrganizationNewsDO organizationNewsDO = organizationNewsService.selectById(recruitmentNews.getOrgId());
//            if (organizationNewsDO != null) {
//                recruitmentNews.setOrgName(organizationNewsDO.getName());
//            }
//        }
        model.addAttribute("recruitmentNews", recruitmentNews);
        return "jzweb/recruitmentNews/info";
    }

    @Log("添加招聘信息")
    @ResponseBody
    @PostMapping("/save")
    @RequiresPermissions("jzweb:recruitmentNews:add")
    public Result<String> save(RecruitmentNewsDO recruitmentNews) {
      //  recruitmentNews.setOrgId(this.getUser().getOrgId());
        //recruitmentNews.setSalaryRange(recruitmentNews.getMinMoney()+"_"+recruitmentNews.getMaxMoney());
//        if(recruitmentNews.getOrgId()==null){
//            recruitmentNews.setOrgId(1251434726664994817L);
//            recruitmentNews.setOrgName("湖南金职伟业母婴护理有限公司");
//        }
//        if(recruitmentNews.getOrgId1()!=null){
//            recruitmentNews.setOrgId(Long.valueOf(recruitmentNews.getOrgId1()));
//            OrganizationNewsDO organizationNewsDO = organizationNewsService.selectById(recruitmentNews.getOrgId1());
//            recruitmentNews.setOrgName(organizationNewsDO.getName());
//        }
        recruitmentNewsService.insert(recruitmentNews);
        return Result.ok();
    }

    /**
     * 下载导入模板
     *
     * @param response
     */
    @RequestMapping("/downloadImportTemplate")
//    @RequiresPermissions("jzweb:recruitmentNews:downloadImportTemplate")
    @ResponseBody
    public void downloadImportTemplate(HttpServletResponse response) {
        List<RecruitmentNowVo> list = new LinkedList<>();
        //导出操作
        EasyPoiUtil.exportExcel(list, "招聘信息导入模板", "招聘信息导入模板", RecruitmentNowVo.class, "招聘信息导入模板", response);
    }
    @Log("导入招聘信息")
    @ResponseBody
    @PostMapping("/import")
//    @RequiresPermissions("jzweb:recruitmentNews:import")
    public Result<?> importExcel(@RequestParam("file") MultipartFile file) throws Exception {
        // 第一步--判断文件格式
        if (!"application/vnd.ms-excel".equals(file.getContentType())) {
            return Result.fail("文件格式错误，请选择.xls文件");
        }

        // 第二步--解析文件获得数据
        List<RecruitmentNowVo> list = EasyPoiUtil.importExcel(file, 1, 1, RecruitmentNowVo.class);
        if (list.size() == 0) {
            return Result.fail("Excel数据为空，请完善");
        }

        // 第三步--判断导入人员身份，获取导入人员信息
        int startRow = 3;
        int cout = 1; // 错误信息计数
        List<RecruitmentNewsDO> upDOList = new ArrayList<>();
        List<ErrorCodeVo> list1 = new ArrayList<>();
        FileUtil fileUtil = new FileUtil();
        for (int i = 0; i < list.size(); i++) {
            StringBuilder sb = new StringBuilder();

            // 第一步验证是否存在空值
            if (org.apache.commons.lang.StringUtils.isBlank(list.get(i).getOrgName())) {
                sb.append("第" + (i + startRow) + "行企业名称未填写，请完善！" + ";");
            } else {
                if (org.apache.commons.lang.StringUtils.isBlank(list.get(i).getOrgProvince())) {
                    sb.append("第" + (i + startRow) + "行所属省份未填写，请完善！" + ";");
                } else  {
                    if (org.apache.commons.lang.StringUtils.isBlank(list.get(i).getOrgCity())){
                        sb.append("第" + (i + startRow) + "行所属市未填写，请完善！" + ";");
                    }else {
                        if (org.apache.commons.lang.StringUtils.isBlank(list.get(i).getOrgAddress())) {
                            sb.append("第" + (i + startRow) + "行所属具体地址未填写，请完善！" + ";");
                        }else {
                            if (org.apache.commons.lang.StringUtils.isBlank(list.get(i).getName())) {
                                sb.append("第" + (i + startRow) + "行岗位名称未填写，请完善！" + ";");
                            }else {
                                if (org.apache.commons.lang.StringUtils.isBlank(String.valueOf(list.get(i).getNumbers()))) {
                                    sb.append("第" + (i + startRow) + "行招聘人数未填写，请完善！" + ";");
                                }
                            }
                        }
                    }
                }

            }

            if (sb.length() > 0) {
                ErrorCodeVo errorCodeVo = new ErrorCodeVo();
                errorCodeVo.setSeq(cout);
                errorCodeVo.setErrorCode(sb.toString());
                list1.add(errorCodeVo);
                cout += 1;
            }else {
                RecruitmentNewsDO recruitmentNowDO = new RecruitmentNewsDO();
                recruitmentNowDO.setOrgName(list.get(i).getOrgName());
                recruitmentNowDO.setOrgProvince(list.get(i).getOrgProvince());
                recruitmentNowDO.setOrgCity(list.get(i).getOrgCity());
                recruitmentNowDO.setOrgAddress(list.get(i).getOrgAddress());
                recruitmentNowDO.setProvince(list.get(i).getOrgProvince());
                recruitmentNowDO.setCity(list.get(i).getOrgCity());
                recruitmentNowDO.setAddress(list.get(i).getOrgAddress());
                recruitmentNowDO.setOrgCode(list.get(i).getOrgCode());

                // 处理企业Logo上传
                if (StringUtils.isNotBlank(list.get(i).getOrgLogo())) {
                    List<String> ossUrls = Arrays.stream(list.get(i).getOrgLogo().split(","))
                            .map(localPath -> {
                                File file1 = new File(localPath);
                                MultipartFile multipartFile = null;
                                try {
                                    multipartFile = new MockMultipartFile(file1.getName(), new FileInputStream(file1));
                                } catch (IOException e) {
                                    throw new RuntimeException(e);
                                }
                                return ossService.uploadFileOssName(multipartFile);
                            })
                            .collect(Collectors.toList());
                    recruitmentNowDO.setOrgLogo(String.join(",", ossUrls));
                }

                recruitmentNowDO.setEducation(list.get(i).getEducation());
                recruitmentNowDO.setOrgRange(list.get(i).getOrgRange());
                recruitmentNowDO.setIntroduce(list.get(i).getIntroduce());
                recruitmentNowDO.setQualification(list.get(i).getQualification());

                // 过滤四字节字符并记录被过滤的字符
                String originalName = list.get(i).getName();
                List<String> filteredChars = new ArrayList<>();
                StringBuilder filteredNameBuilder = new StringBuilder();

                for (int j = 0; j < originalName.length(); ) {
                    int codePoint = originalName.codePointAt(j);
                    if (codePoint <= 0xFFFF) {
                        filteredNameBuilder.appendCodePoint(codePoint);
                    } else {
                        String filteredChar = new String(new int[]{codePoint}, 0, 1);
                        filteredChars.add(filteredChar);
                    }
                    j += Character.charCount(codePoint);
                }

                String filteredName = filteredNameBuilder.toString();
                recruitmentNowDO.setName(filteredName);

                if (!filteredChars.isEmpty()) {
                    String errorInfo = "第" + (i + startRow) + "行岗位名称被过滤字符: " + String.join(",", filteredChars);
                    ErrorCodeVo errorCodeVo = new ErrorCodeVo();
                    errorCodeVo.setSeq(cout);
                    errorCodeVo.setErrorCode(errorInfo);
                    list1.add(errorCodeVo);
                    cout += 1;
                }

                recruitmentNowDO.setSalaryRange(list.get(i).getSalaryRange());
                recruitmentNowDO.setWelfareInroduce(list.get(i).getSalaryRange());
                recruitmentNowDO.setNumbers(list.get(i).getNumbers());
                recruitmentNowDO.setState(0);
                recruitmentNowDO.setStatus(1);
                recruitmentNowDO.setIsTop(0);

                // 新增逻辑：每 6 条数据，createrDate 向后减 3 天
                Calendar calendar = Calendar.getInstance();
                int group = i / 6;
                int daysOffset = group * 3;
                calendar.add(Calendar.DAY_OF_MONTH, -daysOffset);
                recruitmentNowDO.setCreaterDate(calendar.getTime());
                upDOList.add(recruitmentNowDO);
            }


        }

        if (list1.size() == 0) {
            boolean c = recruitmentNewsService.insertOrUpdateBatch(upDOList, upDOList.size());
            if (c) {
                return Result.ok("成功导入" + upDOList.size() + "条数据");
            } else {
                return Result.fail("招聘信息添加错误，请稍后重试或联系管理员");
            }
        } else {
            //导入失败，删除已导入的图片
            for (int fi = 0; fi < list.size(); fi++) {
                if (StringUtils.isNotBlank(list.get(fi).getOrgLogo())) {
                    String url = list.get(fi).getOrgLogo().replace(ValuesUtil.returnUrl, ValuesUtil.localUrl);
                    String imgUrl = url.replace("\\", "/");
                    boolean b1 = fileUtil.DeleteFolder(imgUrl);
                    log.info("导入招聘信息失败删除公司照片第" + (fi + 1) + "张，情况：" + b1);
                }
            }
            JSONArray jsonArray = JSONArray.parseArray(JSON.toJSONString(list1));
            EhCacheUtil.put("test12" + this.getUserId(), jsonArray);
            return Result.build(EnumErrorCode.FileImportError.getCode(), EnumErrorCode.FileImportError.getMsg());
        }
    }

    /**
     * 导出错误信息
     *
     * @param request
     * @param response
     * @throws Exception
     * @author kl
     */
    @Log("导出错误信息")
    @GetMapping("/importError")
    @ResponseBody
    @Transactional
//    @RequiresPermissions("jzweb:recruitmentNews:import")
    public void download(HttpServletRequest request, HttpServletResponse response) throws Exception {
        // 告诉浏览器用什么软件可以打开此文件
        response.setHeader("content-Type", "application/vnd.ms-excel");
        // 下载文件的默认名称
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("招聘信息导入错误信息", "UTF-8") + ".xls");
        //编码
        response.setCharacterEncoding("UTF-8");
        String jsonArray = EhCacheUtil.get("test12" + this.getUserId()).toString();
        JSONArray arrayList = JSONArray.parseArray(jsonArray);
        //转换为目标对象list
        List<ErroeDownVo> groupList = JSONObject.parseArray(arrayList.toJSONString(), ErroeDownVo.class);
        Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), ErroeDownVo.class, groupList);
        workbook.write(response.getOutputStream());
    }
    @Log("修改招聘信息")
    @ResponseBody
    @RequestMapping("/update")
    @RequiresPermissions("jzweb:recruitmentNews:edit")
    public Result<String> update(RecruitmentNewsDO recruitmentNews) {
        recruitmentNews.setOrgId((recruitmentNews.getOrgId()));
       // recruitmentNews.setSalaryRange(recruitmentNews.getMinMoney()+"_"+recruitmentNews.getMaxMoney());
        boolean update = recruitmentNewsService.updateById(recruitmentNews);
        return update ? Result.ok() : Result.fail();
    }

    @Log("删除招聘信息")
    @PostMapping("/remove")
    @ResponseBody
    @RequiresPermissions("jzweb:recruitmentNews:remove")
    public Result<String> remove(Long id) {
        recruitmentNewsService.deleteById(id);
        return Result.ok();
    }

    @Log("批量删除招聘信息")
    @PostMapping("/batchRemove")
    @ResponseBody
    @RequiresPermissions("jzweb:recruitmentNews:batchRemove")
    public Result<String> remove(@RequestParam("ids[]") Long[] ids) {
        recruitmentNewsService.deleteBatchIds(Arrays.asList(ids));
        return Result.ok();
    }

    @Log("岗位上线")
    @PostMapping("/batchUpper")
    @ResponseBody
    @RequiresPermissions("jzweb:courses:batchRemove")
    public Result<String> batchUpper(@RequestParam("ids[]") Long[] ids) {
        List<RecruitmentNewsDO> recruitmentNewsDOS = new ArrayList<>();
        for (Long id : ids) {
            RecruitmentNewsDO recruitmentNewsDO = recruitmentNewsService.selectById(id);
            recruitmentNewsDO.setState(0);
            recruitmentNewsDO.setUpdateDate(new Date());
            recruitmentNewsDOS.add(recruitmentNewsDO);
        }
        boolean bbc = recruitmentNewsService.updateBatchById(recruitmentNewsDOS, recruitmentNewsDOS.size());
        return bbc ? Result.ok() : Result.fail();
    }

    @Log("岗位下线")
    @PostMapping("/batchLower")
    @ResponseBody
    @RequiresPermissions("jzweb:courses:batchRemove")
    public Result<String> batchLower(@RequestParam("ids[]") Long[] ids) {
        List<RecruitmentNewsDO> recruitmentNewsDOS = new ArrayList<>();
        for (Long id : ids) {
            RecruitmentNewsDO recruitmentNewsDO = recruitmentNewsService.selectById(id);
            recruitmentNewsDO.setState(1);
            recruitmentNewsDO.setUpdateDate(new Date());
            recruitmentNewsDOS.add(recruitmentNewsDO);
        }
        boolean bbc = recruitmentNewsService.updateBatchById(recruitmentNewsDOS, recruitmentNewsDOS.size());
        return bbc ? Result.ok() : Result.fail();
    }

}
